var Event = {
    handle: {},

    $watch: function(key, fn) {
        if (!this.handle[key]) {
            this.handle[key] = [];
        }
        this.handle[key].push(fn)
    },

    emit: function(event) {
        var handlerArgs = Array.prototype.splice.call(arguments, 1);
        var eventArr = String.prototype.split.call(event, '.');
        for (var t = 0, arr; arr = eventArr[t++];) {
            if (!this.handle[arr]) {
                continue;
            }
            for (var i = 0, handle; handle = this.handle[arr][i++];) {
                handle.apply(this, handlerArgs);
            }
        }

    }
}

function Observer(data) {
    this.parent = Array.prototype.splice.call(arguments, 1)[0] || 'data';
    this.data = data;
    this.walk(data);

}

var p = Observer.prototype;

p.walk = function(obj) {
    var key,
        val;

    for (key in obj) {
        if (obj.hasOwnProperty(key)) {
            val = obj[key];
            if (typeof val === 'object') {
                new Observer(val, this.parent + '.' + key)
            }
            this.conver(key, val, this.parent)
        }

    }
}

p.conver = function(key, val, parent) {
    console.log(this.data)
    var keys = parent + '.' + key;
    var self = this;
    Object.defineProperty(this.data, key, {
        enumerable: true,
        configurable: true,
        get: function() {
            console.log('你访问了' + key);
            return val
        },
        set: function(newkey) {
            console.log('你设置了' + key + '，新的' + key + '为' + newkey);
            if (typeof newVal === "object" && newVal !== null) {
                // 为对象的属性绑定访问器属性
                new Observer(newVal, parent);
            }
            self.emit(keys, newkey);
            val = newkey
        }
    })
}

function assemble(p, Event) {
    for (var key in Event) {
        p[key] = Event[key]
    }
}

assemble(p, Event);
var app = new Observer({
    name: {
        firstname: 'deng',
        lastname: 'houqiang'
    },
    age: 23
})

app.$watch('name', function(newname) {
    console.log('我的姓名发生了变化，可能是姓氏变了，也可能是名字变了。')
})